#include "StdAfx.h"
#include "Directory.h"

using namespace Adaptive::Foundation::IO;

/*--------------------------------------------------------------------------------
 * Constructor / Dispose / Destructor Methods
 *------------------------------------------------------------------------------*/
#pragma region Constructor / Dispose / Destructor Methods
// <summary>
// Initializes a new instance of the class.
// </summary>
// <remarks>
// This constructor is hidden to prevent instantiation.
// </remarks>
IoDirectory::IoDirectory()
{
}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Public Methods / Functions
 *------------------------------------------------------------------------------*/
#pragma region Public Methods / Functions
// <summary>
// Gets the free space information for the specified drive.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_getdiskfree"/> function.
// </remarks>
// <param name="driveLetter">The letter of the drive to examine.</param>
// <returns>
// A populated <see cref="DiskFreeInfo"/> structure if successful, otherwise, returns
// an empty structure.
// </returns>
DiskFreeInfo IoDirectory::GetDiskFree( String^ driveLetter )
{
	if ((driveLetter == nullptr) || (driveLetter->Length == 0))
		return GetDiskFree((int)-1);
	else
		return GetDiskFree(driveLetter[0]);
}
// <summary>
// Gets the free space information for the specified drive.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_getdiskfree"/> function.
// </remarks>
// <param name="driveLetter">The letter of the drive to examine.</param>
// <returns>
// A populated <see cref="DiskFreeInfo"/> structure if successful, otherwise, returns
// an empty structure.
// </returns>
DiskFreeInfo IoDirectory::GetDiskFree( Char driveLetter )
{
	Char dl = Char::ToUpper(driveLetter);

	if ((dl >= 'A') && (dl <= 'Z'))
		return GetDiskFree( ((int)dl)-65 );
	else
		return GetDiskFree((int)-1);
}
// <summary>
// Gets the free space information for the specified drive.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_getdiskfree"/> function.
// </remarks>
// <param name="driveNumber">The number of the drive to examine.</param>
// <returns>
// A populated <see cref="DiskFreeInfo"/> structure if successful, otherwise, returns
// an empty structure.
// </returns>
DiskFreeInfo IoDirectory::GetDiskFree( int driveNumber )
{
	_diskfree_t info;
	DiskFreeInfo returnValue;
	unsigned int result = 0;

	if (driveNumber != -1)
	{
		result = _getdiskfree(driveNumber+1, &info);
		if (result == 0)
		{
			returnValue.TotalClusters = info.total_clusters;
			returnValue.AvailableClusters = info.avail_clusters;
			returnValue.SectorsPerCluster = info.sectors_per_cluster;
			returnValue.BytesPerSector = info.bytes_per_sector;
		}
	}
	return returnValue;
}
// <summary>
// Gets the list of drives on the system.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_getdrives"/> function.
// </remarks>
// <returns>
// A <see cref="BitArray"/> instance containing the bits of the bitmask identifying the 
// drives that are present.
// </returns>
BitArray^ IoDirectory::GetDrives()
{
	BitArray^ returnValue = nullptr;
	array<int>^	 values = nullptr;
	unsigned long result = 0;

	result = _getdrives();
	values = gcnew array<int>(2);
	values[1] = (int)(result >> 16);
	values[0] = (int)( (result << 16) / (256*256));
	
	returnValue = gcnew BitArray( values );

	delete(values);
	return returnValue;
	
}
// <summary>
// Gets the list of drives on the system.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_getdrives"/> function.
// </remarks>
// <returns>
// A long value containing the bitmask identifying the 
// drives that are present.
// </returns>
unsigned long IoDirectory::GetDrivesAsLong()
{
	return _getdrives();
}
// <summary>
// Searches for a file using environment paths.
// </summary>
// <remarks>
// This is a wrapper method for the C <see cref="_searchenv"/> function.
//
// The <b>SearchEnviron</b> routine searches for the target file in the specified domain. 
// The <i>variableName</i> variable can be any environment or user-defined variable that 
// specifies a list of directory paths, such as PATH, LIB, and INCLUDE. Because <b>SearchEnviron</b> is 
// case-sensitive, <i>variableName</i> should match the case of the environment variable.
// </remarks>
// <param name="fileName">Name of the file to search for.</param>
// <param name="variableName">Environment to search.</param>
// <returns>
// The routine searches first for the file in the current working directory. If it does not find the file, 
// it looks next through the directories specified by the environment variable. If the target file is in one 
// of those directories, the newly created path is returned. If the filename file is not found, 
// an empty string is returned.
// </returns>
String^ IoDirectory::SearchEnviron(String^ fileName, String^ variableName)
{
	CString newFileName = fileName;
	CString newVarName = variableName;
	String^ returnValue = nullptr;

	wchar_t* buffer = NULL;

	buffer = new wchar_t[512];
	memset(buffer, 0, 512);

	_wsearchenv(newFileName, newVarName, buffer);

	returnValue = gcnew String ( buffer );
	delete(buffer);

	return returnValue;
}
#pragma endregion
